package mylittleinvestigations;

import java.util.HashMap;
import java.util.Stack;

public class Debug
{
    public static final boolean DrawHitBoxes = false;
    public static final boolean ShowFps = false;
    private static final boolean TrackTiming = false;
    private static final int TimingRecordingThresholdMs = 50;
    
    private static HashMap<Thread, Stack<Long>> saveTimeMillisecondsStackHashMap = new HashMap<Thread, Stack<Long>>();
    private static HashMap<Thread, Stack<String>> operationNameStackHashMap = new HashMap<Thread, Stack<String>>();
    private static String indentationString = "  ";
    
    public static void StartTimingOperation(String operationName)
    {
        if (!TrackTiming)
        {
            return;
        }
        
        Stack<Long> saveTimeMillisecondsStack = null;
        Stack<String> operationNameStack = null;
        
        if (!saveTimeMillisecondsStackHashMap.containsKey(Thread.currentThread()))
        {
            // If one of the hash maps doesn't contain this key, then we know neither do.
            saveTimeMillisecondsStack = new Stack<Long>();
            saveTimeMillisecondsStackHashMap.put(Thread.currentThread(), saveTimeMillisecondsStack);
            
            operationNameStack = new Stack<String>();
            operationNameStackHashMap.put(Thread.currentThread(), operationNameStack);
        }
        else
        {
            saveTimeMillisecondsStack = saveTimeMillisecondsStackHashMap.get(Thread.currentThread());
            operationNameStack = operationNameStackHashMap.get(Thread.currentThread());
        }
        
        saveTimeMillisecondsStack.push(System.currentTimeMillis());
        operationNameStack.push(operationName);
    }
    
    public static void ReportTimeElapsed()
    {
        if (!TrackTiming)
        {
            return;
        }
        
        Stack<Long> saveTimeMillisecondsStack = saveTimeMillisecondsStackHashMap.get(Thread.currentThread());
        Stack<String> operationNameStack = operationNameStackHashMap.get(Thread.currentThread());
        
        if (!saveTimeMillisecondsStack.empty())
        {
            long saveTimeMilliseconds = saveTimeMillisecondsStack.pop();
            long timeElapsed = System.currentTimeMillis() - saveTimeMilliseconds;
            String operationName = operationNameStack.pop();
            
            if (timeElapsed > TimingRecordingThresholdMs)
            {
                for (int i = 0; i < saveTimeMillisecondsStack.size(); i++)
                {
                    System.out.print(indentationString);
                }

                System.out.println(operationName + " took " + timeElapsed + " ms.");
            }
        }
        
        // In order not to leak threads, we'll remove each key from the hash maps
        // when their corresponding stacks are empty.
        if (saveTimeMillisecondsStack.empty())
        {
            saveTimeMillisecondsStackHashMap.remove(Thread.currentThread());
            operationNameStackHashMap.remove(Thread.currentThread());
        }
    }
}
